﻿/*****************************************************************//**
 * @file    FITKGraphObjectBC.h
 * @brief   Graph object for all kinds of BC data.
 *
 * @author  ChengHaotian (yeguangbaozi@foxmail.com)
 * @date    2024-04-13
 *********************************************************************/

#ifndef __FITKGRAPHOBJECTBC_H__
#define __FITKGRAPHOBJECTBC_H__

#include "FITKGraphObjectNodeLoadBase.h"

#include "FITKVTKGraphAdaptorAPI.h"

#include <QColor>

// Forward declaration
class vtkArrowSource;
class vtkConeSource;
class vtkPolyData;
class vtkSelectionNode;
class vtkSelection;
class vtkExtractSelection;

class FITKGraphActor;

namespace Comp
{
    class FITKGraphRender;
}

namespace Interface
{
    class FITKAbaBoundaryConditionDisplacement;
    class FITKAbaBoundaryConditionSymmetry;
    class FITKAbaBoundaryConditionVelocity;
    class FITKModelSet;
    class FITKAbaRefPoint;
    class FITKBoundaryLocation;
    class FITKCoordinateSystem;
}

namespace Exchange
{
    /**
     * @brief   Graph object for fixed-sized BC.
     * @author  ChengHaotian (yeguangbaozi@foxmail.com)
     * @date    2024-04-13
     */
    class FITKVTKGRAPHADAPTORAPI FITKGraphObjectBC : public FITKGraphObjectNodeLoadBase
    {
        // Regist
        FITKGraphObjectRegist(FITKGraphObjectBC, FITKGraphObjectNodeLoadBase);
        FITKCLASS(Exchange, FITKGraphObjectBC);

    public:
        /**
         * @brief   Constructor.
         * @param   caseData: The case data
         * @param   bcData: The disp BC data object
         * @param   stepId: The step id
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-13
         */
        FITKGraphObjectBC(AbaqusData::FITKDataCase* caseData, Interface::FITKAbaBoundaryConditionDisplacement* bcData, int stepId);

        /**
         * @brief   Constructor.
         * @param   caseData: The case data
         * @param   bcData: The symmetry BC data object
         * @param   stepId: The step id
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        FITKGraphObjectBC(AbaqusData::FITKDataCase* caseData, Interface::FITKAbaBoundaryConditionSymmetry* bcData, int stepId);

        /**
         * @brief   Constructor.
         * @param   caseData: The case data
         * @param   bcData: The velocity BC data object
         * @param   stepId: The step id
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-05
         */
        FITKGraphObjectBC(AbaqusData::FITKDataCase* caseData, Interface::FITKAbaBoundaryConditionVelocity* bcData, int stepId);

        /**
         * @brief   Destructor.[virtual]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-13
         */
        virtual ~FITKGraphObjectBC();

        /**
         * @brief   Dis-highlight the BC graph actors.[override]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        void disHighlight() override;

        /**
         * @brief   Show or hide graph object.[override]
         * @param   visibility: The visibility of graph object
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-24
         */
        void setVisible(bool visibility) override;

        /**
         * @brief   Update the BC actors by current step.[override]
         * @param   forceUpdate: Force update[default]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        void update(bool forceUpdate = false) override;

        /**
         * @brief   Update the visibility with data object's visibility.[override]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-05-14
         */
        void updateVisibility() override;

    private:
        /**
         * @brief   Initialize the source data for glyph.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        void initSource();

        /**
         * @brief   Get the value to member variables.[override]
         * @param   stepId: The step id
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        void getValue(int stepId) override;

        /**
         * @brief   Clear the poly data and filters after creating the BC glyphs.[override]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        void clearCache() override;

        /**
         * @brief   Insert a new point and its value to points and data.[override]
         * @param   pos: The position of point
         * @param   modelId: The model id of this point
         * @param   addToLoadPoints: Add the point to the BC points data[default]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-13
         */
        void insertNextPoint(double* pos, int modelId, bool addToLoadPoints = true) override;

        /**
         * @brief   Insert a new point and its value to points and data.
         * @param   points: The vtkPoints
         * @param   cells: The vtkCellArray
         * @param   pos: The position of point
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-13
         */
        void insertNextPoint(vtkPoints* points, vtkCellArray* cells, double* pos);

        /**
         * @brief   Insert the single glyph poly data's data.
         * @param   pos: The position of point
         * @param   modelId: The model id of this point
         * @param   direction: The direction of BC without symbol
         * @param   addToLoadPoints: Add the point to the BC points data
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        void insertNextSinglePoint(double* pos, int modelId, double* direction, bool addToLoadPoints);

        /**
         * @brief   Insert the double glyph poly data's data.
         * @param   pos: The position of point
         * @param   modelId: The model id of this point
         * @param   direction: The direction of BC without symbol
         * @param   addToLoadPoints: Add the point to the BC points data
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        void insertNextDoublePoint(double* pos, int modelId, double* direction, bool addToLoadPoints);

        /**
         * @brief   Generate the poly data for the BC.[override]
         * @param   bc: The BC data object
         * @return  Is OK
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-05-14
         */
        bool generatePolyData(Interface::FITKBoundaryLocation* bc) override;

        // This function is abandoned in this class, use 'generateGraphs' instead.
        /**
         * @brief   Generate BC actor.[override]
         * @param   src: The source data
         * @param   size: The actor size ( -1 means use default fixed size )[default]
         * @param   details: The additional information[default]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-10
         */
        void generateGraph(vtkPolyDataAlgorithm* src, double size = -1., QVariant details = QVariant()) override;

        /**
         * @brief   Generate BC actors.
         * @param   size: The actor size ( -1 means use default fixed size )[default]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        void generateGraphs(double size = -1.);

        /**
         * @brief   Initialize the actor's visualization properties.[override]
         * @param   actor: The actor
         * @param   details: The type of actor( 1: Displacement, 2: Rotation )[default]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-13
         */
        void initActorProperties(vtkProp* actor, QVariant details = QVariant()) override;

        /**
         * @brief   Show the actors need to be visualized to the graph window, and hide the other actors.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-16
         */
        void showActors();

        /**
         * @brief   Check if the data has been changed for additional data.( Such as coodinate. )[override]
         * @return  Has been changed
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-05-29
         */
        bool checkDataChanged() override;

    private:
        /**
         * @brief   The color for the single arrow or cone.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-16
         */
        QColor m_color_1 = Qt::white;

        /**
         * @brief   The color for the double arrows or cones.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-16
         */
        QColor m_color_2 = Qt::white;

        /**
         * @brief   The displacement and rotation value.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-13
         */
        double m_value[6]{ 0, 0, 0, 0, 0, 0 };

        /**
         * @brief   The displacement and rotation enable states value.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        int m_enableStates[6]{ 0, 0, 0, 0, 0, 0 };

        /**
         * @brief   The positive or negative directions of three directions.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-05-29
         */
        int m_symbolDirecs_1[3]{ 1, 1, 1 };

        /**
         * @brief   The positive or negative directions of three directions.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-05-29
         */
        int m_symbolDirecs_2[3]{ 1, 1, 1 };

        /**
         * @brief   The arrow source for enabled none-zero displacement  BC.( The rotation BC's source will deep copy this one )
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        vtkArrowSource* m_arrowSource{ nullptr };

        /**
         * @brief   The cone source for enabled zero displacement BC.( The rotation BC's source will deep copy this one )
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        vtkConeSource* m_coneSource{ nullptr };

        // Additional data for displacement and rotation BC.
        // The 'm_polyData', 'm_points', 'm_cells', 'm_normal' and 'm_scalar' are abandonded in this class,
        // use the data list with the enum '_DataIndex' instead.
        //@{
        /**
         * @brief   The poly data list for creating BC.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        QList<vtkPolyData*> m_polyDataList;

        /**
         * @brief   The points data list.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        QList<vtkPoints*> m_pointsList;

        /**
         * @brief   The cells data list.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        QList<vtkCellArray*> m_cellsList;

        /**
         * @brief   The normal data list for creating BC.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        QList<vtkDoubleArray*> m_normalList;

        /**
         * @brief   The scalar data list for creating BC.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-04-15
         */
        QList<vtkDoubleArray*> m_scalarList;

        /**
         * @brief   The model id array list for all poly data.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-05-14
         */
        QList<vtkIntArray*> m_modelIdArrayList;
        //@}

        // Extractor.
        //@{
        /**
         * @brief   The selection node list for extract mesh grid.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-05-14
         */
        QList<vtkSelectionNode*> m_selectNodeList;

        /**
         * @brief   The selection list for vtkSelectionNode.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-05-14
         */
        QList<vtkSelection*> m_sectionList;

        /**
         * @brief   The mesh grid extractor list.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-05-14
         */
        QList<vtkExtractSelection*> m_extractSelectionList;

        /**
         * @brief   The indice array of extract id.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-05-14
         */
        QList<vtkIdTypeArray*> m_idArrayList;
        //@}

        /**
         * @brief   The coordinate transform data object.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-05-29
         */
        Interface::FITKCoordinateSystem* m_coordinate{ nullptr };

        /**
         * @brief   The coordinate system ID.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-05-29
         */
        int m_coordinateId = -1;

    };

    // Type define.
    typedef FITKGraphObjectBC FITKGraphObjectBCDisplacement;
    typedef FITKGraphObjectBC FITKGraphObjectBCSymmetry;
}   // namespace Exchange

#endif // __FITKGRAPHOBJECTBC_H__
